package jp.co.piratealliance.pirateAllianceWeb.common.db.interceptor;

import java.sql.Connection;
import java.util.Properties;

import jp.co.piratealliance.pirateAllianceWeb.common.db.LimitOffsetPagingSqlRewriter;
import jp.co.piratealliance.pirateAllianceWeb.common.util.StringUtils;
import jp.co.piratealliance.pirateAllianceWeb.def.Constants;
import jp.co.piratealliance.pirateAllianceWeb.helper.WebHelper;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.RowBounds;


/**
 * copyright pirate alliance team 2014
 *
 * @author xuwei
 *
 */
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PagingInterceptor implements Interceptor
{

	public Object intercept(Invocation invocation) throws Throwable
	{
		StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = statementHandler.getBoundSql();
        MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
        String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");

        String startRow = WebHelper.getRequest().getParameter("start_row");
        String endRow = WebHelper.getRequest().getParameter("end_row");

        int limit = 5;
        int offset = 0;

        if(StringUtils.isNotEmpty(startRow) && StringUtils.isNotEmpty(endRow))
        {
        	int start = Integer.valueOf(startRow);
        	offset = start;
        	limit = Integer.valueOf(endRow) - start + 1;
        }

        metaStatementHandler.setValue("delegate.boundSql.sql", LimitOffsetPagingSqlRewriter.makeLimitOffsetSql(originalSql, limit, offset));

        metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);

        metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);

		return invocation.proceed();
	}

	public Object plugin(Object target)
	{
	 	if (target instanceof StatementHandler) {
			StatementHandler statementHandler = (StatementHandler) target;
			MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
			MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
			if (mappedStatement.getId().endsWith(Constants.PAGING_SQL_SUFFIX_STRING)) {
				return Plugin.wrap(target, this);
			}
		}

		return target;
	}

	public void setProperties(Properties properties)
	{
		// TODO Auto-generated method stub

	}

}
